<template>
  <div class="practice-area">
    <div class="practice-header">
      <h2>练习区</h2>
      <p>通过实践提升编程技能，巩固学习成果</p>
    </div>

    <div class="practice-content">
      <!-- 练习分类和筛选 -->
      <div class="filter-section">
        <el-select v-model="selectedCategory" placeholder="练习分类" @change="handleCategoryChange">
          <el-option label="全部" value="" />
          <el-option label="算法练习" value="algorithm" />
          <el-option label="前端开发" value="frontend" />
          <el-option label="后端开发" value="backend" />
          <el-option label="数据库" value="database" />
          <el-option label="系统设计" value="system" />
        </el-select>
        <el-select v-model="selectedDifficulty" placeholder="难度等级" @change="handleDifficultyChange">
          <el-option label="全部" value="" />
          <el-option label="入门" value="easy" />
          <el-option label="简单" value="simple" />
          <el-option label="中等" value="medium" />
          <el-option label="困难" value="hard" />
          <el-option label="挑战" value="challenge" />
        </el-select>
        <el-select v-model="selectedStatus" placeholder="完成状态" @change="handleStatusChange">
          <el-option label="全部" value="" />
          <el-option label="未开始" value="not_started" />
          <el-option label="进行中" value="in_progress" />
          <el-option label="已完成" value="completed" />
        </el-select>
      </div>

      <!-- 练习列表 -->
      <div class="practice-list">
        <el-row :gutter="20">
          <el-col :span="8" v-for="practice in filteredPractices" :key="practice.id">
            <el-card class="practice-card" :body-style="{ padding: '0px' }">
              <div class="practice-info">
                <div class="practice-header">
                  <h4>{{ practice.title }}</h4>
                  <el-tag :type="getDifficultyTag(practice.difficulty)">{{ practice.difficulty }}</el-tag>
                </div>
                <p class="practice-desc">{{ practice.description }}</p>
                <div class="practice-meta">
                  <span><el-icon><Timer /></el-icon> {{ practice.estimatedTime }}</span>
                  <span><el-icon><User /></el-icon> {{ practice.completionRate }}%完成率</span>
                  <span><el-icon><Star /></el-icon> {{ practice.points }}积分</span>
                </div>
                <div class="practice-progress" v-if="practice.progress">
                  <el-progress :percentage="practice.progress" :status="getProgressStatus(practice.progress)" />
                </div>
                <div class="practice-actions">
                  <el-button type="primary" @click="startPractice(practice)">开始练习</el-button>
                  <el-button @click="viewPracticeDetail(practice)">查看详情</el-button>
                </div>
              </div>
            </el-card>
          </el-col>
        </el-row>
      </div>

      <!-- 分页 -->
      <div class="pagination-section">
        <el-pagination
          v-model:current-page="currentPage"
          v-model:page-size="pageSize"
          :total="totalPractices"
          :page-sizes="[9, 18, 27, 36]"
          layout="total, sizes, prev, pager, next"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
        />
      </div>
    </div>

    <!-- 练习详情对话框 -->
    <el-dialog
      v-model="practiceDialogVisible"
      :title="selectedPractice?.title"
      width="80%"
      class="practice-dialog"
      @close="handleDialogClose"
    >
      <div v-if="selectedPractice" class="practice-detail">
        <div class="detail-header">
          <div class="detail-info">
            <h3>{{ selectedPractice.title }}</h3>
            <p>{{ selectedPractice.description }}</p>
            <div class="detail-meta">
              <el-tag :type="getDifficultyTag(selectedPractice.difficulty)">
                {{ selectedPractice.difficulty }}
              </el-tag>
              <span>预计用时：{{ selectedPractice.estimatedTime }}</span>
              <span>完成率：{{ selectedPractice.completionRate }}%</span>
              <span>积分：{{ selectedPractice.points }}</span>
            </div>
          </div>
        </div>

        <div class="detail-content">
          <el-tabs v-model="activeTab" @tab-change="handleTabChange">
            <el-tab-pane label="练习说明" name="description">
              <div class="practice-instructions">
                <h4>练习目标</h4>
                <p>{{ selectedPractice.objectives }}</p>
                <h4>具体要求</h4>
                <ul>
                  <li v-for="(requirement, index) in selectedPractice.requirements" :key="index">
                    {{ requirement }}
                  </li>
                </ul>
                <h4>评分标准</h4>
                <el-table :data="selectedPractice.scoringCriteria" border>
                  <el-table-column prop="criteria" label="评分项" />
                  <el-table-column prop="points" label="分值" width="100" />
                </el-table>
              </div>
            </el-tab-pane>

            <el-tab-pane label="在线编码" name="coding">
              <div class="coding-environment">
                <div class="editor-section">
                  <div class="editor-header">
                    <span>代码编辑器</span>
                    <div class="editor-actions">
                      <el-button type="primary" @click="runCode">运行代码</el-button>
                      <el-button type="success" @click="submitCode">提交答案</el-button>
                      <el-button @click="resetCode">重置代码</el-button>
                    </div>
                  </div>
                  <div class="code-editor">
                    <!-- 这里集成代码编辑器组件 -->
                    <div ref="editorContainer" class="editor-container"></div>
                  </div>
                </div>
                <div class="output-section">
                  <div class="output-header">
                    <span>运行结果</span>
                    <el-button @click="clearOutput">清除输出</el-button>
                  </div>
                  <div class="output-content">
                    <pre>{{ codeOutput }}</pre>
                  </div>
                </div>
              </div>
            </el-tab-pane>

            <el-tab-pane label="参考答案" name="solution">
              <div class="solution-content">
                <h4>参考代码</h4>
                <pre class="solution-code">{{ selectedPractice.solution }}</pre>
                <h4>解题思路</h4>
                <p>{{ selectedPractice.solutionExplanation }}</p>
                <h4>知识点</h4>
                <el-tag 
                  v-for="point in selectedPractice.keyPoints" 
                  :key="point"
                  class="key-point-tag"
                >
                  {{ point }}
                </el-tag>
              </div>
            </el-tab-pane>

            <el-tab-pane label="讨论区" name="discussion">
              <div class="discussion-content">
                <div class="discussion-list">
                  <div v-for="comment in selectedPractice.discussions" :key="comment.id" class="discussion-item">
                    <div class="comment-header">
                      <el-avatar :src="comment.userAvatar" />
                      <span class="username">{{ comment.username }}</span>
                      <span class="time">{{ comment.time }}</span>
                    </div>
                    <div class="comment-content">{{ comment.content }}</div>
                    <div class="comment-actions">
                      <el-button text @click="likeComment(comment)">
                        <el-icon><Star /></el-icon>
                        {{ comment.likes }}
                      </el-button>
                      <el-button text @click="replyComment(comment)">
                        <el-icon><ChatLineRound /></el-icon>
                        回复
                      </el-button>
                    </div>
                    
                    <!-- 回复列表 -->
                    <div v-if="comment.replies && comment.replies.length > 0" class="replies-list">
                      <div v-for="reply in comment.replies" :key="reply.id" class="reply-item">
                        <div class="reply-header">
                          <el-avatar :size="24" :src="reply.userAvatar" />
                          <span class="username">{{ reply.username }}</span>
                          <span class="time">{{ reply.time }}</span>
                        </div>
                        <div class="reply-content">{{ reply.content }}</div>
                        <div class="reply-actions">
                          <el-button text @click="likeComment(reply)">
                            <el-icon><Star /></el-icon>
                            {{ reply.likes }}
                          </el-button>
                        </div>
                      </div>
                    </div>
                    
                    <!-- 回复输入框 -->
                    <div v-if="replyToComment && replyToComment.id === comment.id" class="reply-input">
                      <el-input
                        v-model="replyContent"
                        type="textarea"
                        :rows="2"
                        placeholder="回复评论..."
                      />
                      <div class="reply-actions">
                        <el-button @click="cancelReply">取消</el-button>
                        <el-button type="primary" @click="submitReply">发表回复</el-button>
                      </div>
                    </div>
                  </div>
                </div>
                <div class="comment-input">
                  <el-input
                    v-model="newComment"
                    type="textarea"
                    :rows="3"
                    placeholder="发表你的评论..."
                  />
                  <el-button type="primary" @click="submitComment">发表评论</el-button>
                </div>
              </div>
            </el-tab-pane>
          </el-tabs>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup>
import { ref, computed, onMounted } from 'vue'
import { Timer, User, Star, ChatLineRound } from '@element-plus/icons-vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import * as monaco from 'monaco-editor'

// 筛选条件
const selectedCategory = ref('')
const selectedDifficulty = ref('')
const selectedStatus = ref('')
const currentPage = ref(1)
const pageSize = ref(9)
const totalPractices = ref(100)

// 练习数据
const practices = ref([
  {
    id: 1,
    title: '实现Vue3响应式系统',
    description: '使用Vue3的组合式API实现一个简单的响应式系统',
    category: '前端开发',
    difficulty: '中等',
    estimatedTime: '2小时',
    completionRate: 45,
    points: 100,
    progress: 60,
    objectives: '理解Vue3响应式系统的核心原理，掌握ref和reactive的使用方法',
    requirements: [
      '实现ref的基本功能',
      '实现reactive的基本功能',
      '实现计算属性computed',
      '实现watch和watchEffect'
    ],
    scoringCriteria: [
      { criteria: '功能完整性', points: 40 },
      { criteria: '代码质量', points: 30 },
      { criteria: '性能优化', points: 20 },
      { criteria: '文档说明', points: 10 }
    ],
    solution: `import { ref, reactive, computed, watch } from 'vue'

// 实现ref
function createRef(value) {
  return {
    value,
    __v_isRef: true
  }
}

// 实现reactive
function reactive(target) {
  return new Proxy(target, {
    get(target, key) {
      track(target, key)
      return target[key]
    },
    set(target, key, value) {
      target[key] = value
      trigger(target, key)
      return true
    }
  })
}`,
    solutionExplanation: '通过Proxy实现响应式系统，使用track和trigger实现依赖收集和触发更新',
    keyPoints: ['Proxy', '响应式原理', '依赖收集', '触发更新'],
    discussions: [
      {
        id: 1,
        username: '张三',
        userAvatar: 'https://placeholder.com/40x40',
        content: '这个练习对理解Vue3的响应式原理很有帮助',
        time: '2024-03-15 14:30',
        likes: 12,
        replies: [
          {
            id: 11,
            username: '李四',
            userAvatar: 'https://placeholder.com/40x40',
            content: '确实，我也学到了很多',
            time: '2024-03-15 15:20',
            likes: 3
          }
        ]
      }
    ],
    initialCode: `// 在这里实现Vue3的响应式系统
// 提示：使用Proxy实现响应式，并实现track和trigger函数

function track(target, key) {
  // 实现依赖收集
}

function trigger(target, key) {
  // 实现触发更新
}

function createRef(value) {
  // 实现ref
}

function reactive(target) {
  // 实现reactive
}

// 测试代码
const state = reactive({
  count: 0
})

console.log(state.count) // 应该触发track
state.count++ // 应该触发trigger
console.log(state.count) // 应该输出1
`
  },
  {
    id: 2,
    title: '实现简单的前端路由',
    description: '使用原生JavaScript实现一个简单的前端路由系统',
    category: '前端开发',
    difficulty: '简单',
    estimatedTime: '1小时',
    completionRate: 65,
    points: 80,
    progress: 0,
    objectives: '理解前端路由的基本原理，掌握路由的实现方法',
    requirements: [
      '实现路由注册功能',
      '实现路由跳转功能',
      '实现路由参数获取功能',
      '实现路由守卫功能'
    ],
    scoringCriteria: [
      { criteria: '功能完整性', points: 40 },
      { criteria: '代码质量', points: 30 },
      { criteria: '性能优化', points: 20 },
      { criteria: '文档说明', points: 10 }
    ],
    solution: `class Router {
  constructor() {
    this.routes = {}
    this.currentPath = ''
    
    // 监听hash变化
    window.addEventListener('hashchange', this.handleHashChange.bind(this))
    // 初始化
    window.addEventListener('load', this.handleHashChange.bind(this))
  }
  
  // 注册路由
  register(path, component) {
    this.routes[path] = component
  }
  
  // 处理hash变化
  handleHashChange() {
    const hash = window.location.hash.slice(1) || '/'
    this.currentPath = hash
    this.render()
  }
  
  // 渲染组件
  render() {
    const component = this.routes[this.currentPath]
    if (component) {
      document.getElementById('app').innerHTML = component()
    }
  }
  
  // 路由跳转
  push(path) {
    window.location.hash = path
  }
  
  // 获取参数
  getParams() {
    const hash = window.location.hash
    const queryString = hash.split('?')[1]
    if (!queryString) return {}
    
    return queryString.split('&').reduce((params, param) => {
      const [key, value] = param.split('=')
      params[key] = value
      return params
    }, {})
  }
  
  // 路由守卫
  beforeEach(callback) {
    this.beforeEachCallback = callback
  }
  
  afterEach(callback) {
    this.afterEachCallback = callback
  }
}`,
    solutionExplanation: '通过监听hash变化实现前端路由，支持路由注册、跳转、参数获取和路由守卫功能',
    keyPoints: ['Hash路由', 'History路由', '路由守卫', '参数获取'],
    discussions: [
      {
        id: 2,
        username: '王五',
        userAvatar: 'https://placeholder.com/40x40',
        content: '这个练习让我理解了前端路由的原理',
        time: '2024-03-14 10:15',
        likes: 8,
        replies: []
      }
    ],
    initialCode: `// 在这里实现一个简单的前端路由系统
// 提示：使用hash变化或history API实现路由

class Router {
  constructor() {
    // 初始化路由系统
  }
  
  // 注册路由
  register(path, component) {
    // 实现路由注册
  }
  
  // 处理路由变化
  handleRouteChange() {
    // 实现路由变化处理
  }
  
  // 渲染组件
  render() {
    // 实现组件渲染
  }
  
  // 路由跳转
  push(path) {
    // 实现路由跳转
  }
  
  // 获取参数
  getParams() {
    // 实现参数获取
  }
}

// 测试代码
const router = new Router()

router.register('/', () => '<h1>首页</h1>')
router.register('/about', () => '<h1>关于我们</h1>')
router.register('/user/:id', () => {
  const params = router.getParams()
  return \`<h1>用户页面</h1><p>用户ID: \${params.id}</p>\`
})

// 初始化渲染
router.render()
`
  },
  {
    id: 3,
    title: '实现简单的状态管理',
    description: '使用JavaScript实现一个简单的状态管理系统',
    category: '前端开发',
    difficulty: '中等',
    estimatedTime: '1.5小时',
    completionRate: 35,
    points: 90,
    progress: 30,
    objectives: '理解状态管理的基本原理，掌握状态管理的实现方法',
    requirements: [
      '实现状态存储功能',
      '实现状态更新功能',
      '实现状态订阅功能',
      '实现状态持久化功能'
    ],
    scoringCriteria: [
      { criteria: '功能完整性', points: 40 },
      { criteria: '代码质量', points: 30 },
      { criteria: '性能优化', points: 20 },
      { criteria: '文档说明', points: 10 }
    ],
    solution: `class Store {
  constructor(options = {}) {
    this.state = options.state || {}
    this.mutations = options.mutations || {}
    this.actions = options.actions || {}
    this.subscribers = []
    
    // 初始化持久化
    if (options.persist) {
      this.loadFromStorage()
    }
  }
  
  // 获取状态
  getState() {
    return this.state
  }
  
  // 提交修改
  commit(type, payload) {
    if (this.mutations[type]) {
      this.mutations[type](this.state, payload)
      this.notifySubscribers()
      
      // 持久化
      if (this.persist) {
        this.saveToStorage()
      }
    }
  }
  
  // 分发动作
  dispatch(type, payload) {
    if (this.actions[type]) {
      return this.actions[type]({
        commit: this.commit.bind(this),
        state: this.state
      }, payload)
    }
  }
  
  // 订阅状态变化
  subscribe(callback) {
    this.subscribers.push(callback)
    return () => {
      const index = this.subscribers.indexOf(callback)
      if (index > -1) {
        this.subscribers.splice(index, 1)
      }
    }
  }
  
  // 通知订阅者
  notifySubscribers() {
    this.subscribers.forEach(callback => callback(this.state))
  }
  
  // 保存到本地存储
  saveToStorage() {
    localStorage.setItem('store', JSON.stringify(this.state))
  }
  
  // 从本地存储加载
  loadFromStorage() {
    const savedState = localStorage.getItem('store')
    if (savedState) {
      this.state = JSON.parse(savedState)
    }
  }
}`,
    solutionExplanation: '通过发布订阅模式实现状态管理，支持状态存储、更新、订阅和持久化功能',
    keyPoints: ['发布订阅模式', '状态管理', '持久化', '单向数据流'],
    discussions: [
      {
        id: 3,
        username: '赵六',
        userAvatar: 'https://placeholder.com/40x40',
        content: '这个练习让我理解了Vuex和Redux的原理',
        time: '2024-03-13 16:45',
        likes: 15,
        replies: []
      }
    ],
    initialCode: `// 在这里实现一个简单的状态管理系统
// 提示：使用发布订阅模式实现状态管理

class Store {
  constructor(options = {}) {
    // 初始化状态管理系统
  }
  
  // 获取状态
  getState() {
    // 实现状态获取
  }
  
  // 提交修改
  commit(type, payload) {
    // 实现状态修改
  }
  
  // 分发动作
  dispatch(type, payload) {
    // 实现动作分发
  }
  
  // 订阅状态变化
  subscribe(callback) {
    // 实现状态订阅
  }
  
  // 通知订阅者
  notifySubscribers() {
    // 实现订阅者通知
  }
}

// 测试代码
const store = new Store({
  state: {
    count: 0,
    todos: []
  },
  mutations: {
    increment(state) {
      state.count++
    },
    addTodo(state, todo) {
      state.todos.push(todo)
    }
  },
  actions: {
    asyncIncrement({ commit }) {
      setTimeout(() => {
        commit('increment')
      }, 1000)
    }
  }
})

// 订阅状态变化
store.subscribe(state => {
  console.log('状态变化:', state)
})

// 修改状态
store.commit('increment')
store.commit('addTodo', { id: 1, text: '学习状态管理' })

// 分发动作
store.dispatch('asyncIncrement')
`
  },
  {
    id: 4,
    title: '实现简单的虚拟DOM',
    description: '使用JavaScript实现一个简单的虚拟DOM系统',
    category: '前端开发',
    difficulty: '困难',
    estimatedTime: '3小时',
    completionRate: 25,
    points: 120,
    progress: 0,
    objectives: '理解虚拟DOM的基本原理，掌握虚拟DOM的实现方法',
    requirements: [
      '实现虚拟DOM节点创建',
      '实现虚拟DOM diff算法',
      '实现虚拟DOM渲染',
      '实现虚拟DOM更新'
    ],
    scoringCriteria: [
      { criteria: '功能完整性', points: 40 },
      { criteria: '代码质量', points: 30 },
      { criteria: '性能优化', points: 20 },
      { criteria: '文档说明', points: 10 }
    ],
    solution: `// 虚拟DOM节点
class VNode {
  constructor(tag, props, children) {
    this.tag = tag
    this.props = props || {}
    this.children = children || []
  }
}

// 创建虚拟DOM
function h(tag, props, ...children) {
  return new VNode(tag, props, children.flat())
}

// 渲染虚拟DOM
function render(vnode, container) {
  const el = document.createElement(vnode.tag)
  
  // 设置属性
  for (const key in vnode.props) {
    if (key.startsWith('on')) {
      // 事件处理
      const eventName = key.slice(2).toLowerCase()
      el.addEventListener(eventName, vnode.props[key])
    } else {
      // 普通属性
      el.setAttribute(key, vnode.props[key])
    }
  }
  
  // 渲染子节点
  for (const child of vnode.children) {
    if (typeof child === 'string') {
      el.appendChild(document.createTextNode(child))
    } else {
      render(child, el)
    }
  }
  
  container.appendChild(el)
  return el
}

// 简单的diff算法
function diff(oldVNode, newVNode) {
  // 如果标签不同，直接替换
  if (oldVNode.tag !== newVNode.tag) {
    return {
      type: 'REPLACE',
      node: newVNode
    }
  }
  
  // 如果都是文本节点
  if (typeof oldVNode === 'string' && typeof newVNode === 'string') {
    if (oldVNode !== newVNode) {
      return {
        type: 'TEXT',
        content: newVNode
      }
    }
    return null
  }
  
  // 属性变化
  const propsPatches = {}
  let hasPropsChanges = false
  
  // 检查属性变化
  for (const key in newVNode.props) {
    if (oldVNode.props[key] !== newVNode.props[key]) {
      propsPatches[key] = newVNode.props[key]
      hasPropsChanges = true
    }
  }
  
  // 检查删除的属性
  for (const key in oldVNode.props) {
    if (!(key in newVNode.props)) {
      propsPatches[key] = null
      hasPropsChanges = true
    }
  }
  
  // 子节点变化
  const childrenPatches = []
  const oldChildren = oldVNode.children
  const newChildren = newVNode.children
  
  // 检查子节点变化
  for (let i = 0; i < Math.max(oldChildren.length, newChildren.length); i++) {
    const oldChild = oldChildren[i]
    const newChild = newChildren[i]
    
    if (!oldChild && newChild) {
      // 新增子节点
      childrenPatches.push({
        type: 'ADD',
        node: newChild,
        index: i
      })
    } else if (oldChild && !newChild) {
      // 删除子节点
      childrenPatches.push({
        type: 'REMOVE',
        index: i
      })
    } else if (oldChild && newChild) {
      // 更新子节点
      const childPatch = diff(oldChild, newChild)
      if (childPatch) {
        childrenPatches.push({
          type: 'UPDATE',
          patch: childPatch,
          index: i
        })
      }
    }
  }
  
  // 返回补丁
  return {
    type: 'NODE',
    propsPatches: hasPropsChanges ? propsPatches : null,
    childrenPatches: childrenPatches.length > 0 ? childrenPatches : null
  }
}`,
    solutionExplanation: '通过实现虚拟DOM节点、渲染函数和diff算法，实现一个简单的虚拟DOM系统',
    keyPoints: ['虚拟DOM', 'Diff算法', '渲染函数', '节点更新'],
    discussions: [
      {
        id: 4,
        username: '钱七',
        userAvatar: 'https://placeholder.com/40x40',
        content: '这个练习让我理解了React和Vue的虚拟DOM原理',
        time: '2024-03-12 09:30',
        likes: 20,
        replies: []
      }
    ],
    initialCode: `// 在这里实现一个简单的虚拟DOM系统
// 提示：实现虚拟DOM节点、渲染函数和diff算法

// 虚拟DOM节点
class VNode {
  constructor(tag, props, children) {
    // 实现虚拟DOM节点
  }
}

// 创建虚拟DOM
function h(tag, props, ...children) {
  // 实现虚拟DOM创建
}

// 渲染虚拟DOM
function render(vnode, container) {
  // 实现虚拟DOM渲染
}

// 简单的diff算法
function diff(oldVNode, newVNode) {
  // 实现虚拟DOM diff算法
}

// 测试代码
const app = document.getElementById('app')

// 创建虚拟DOM
const vnode = h('div', { class: 'container' }, [
  h('h1', {}, '虚拟DOM示例'),
  h('p', {}, '这是一个简单的虚拟DOM实现')
])

// 渲染虚拟DOM
render(vnode, app)

// 更新虚拟DOM
setTimeout(() => {
  const newVnode = h('div', { class: 'container' }, [
    h('h1', {}, '虚拟DOM已更新'),
    h('p', {}, '这是一个更新后的虚拟DOM')
  ])
  
  // 计算差异并应用
  const patches = diff(vnode, newVnode)
  // 这里应该实现patch函数来应用差异
  console.log('差异:', patches)
}, 2000)
`
  },
  {
    id: 5,
    title: '实现简单的Promise',
    description: '使用JavaScript实现一个简单的Promise类',
    category: '前端开发',
    difficulty: '中等',
    estimatedTime: '2小时',
    completionRate: 40,
    points: 100,
    progress: 0,
    objectives: '理解Promise的基本原理，掌握Promise的实现方法',
    requirements: [
      '实现Promise的基本功能',
      '实现Promise的链式调用',
      '实现Promise的错误处理',
      '实现Promise的静态方法'
    ],
    scoringCriteria: [
      { criteria: '功能完整性', points: 40 },
      { criteria: '代码质量', points: 30 },
      { criteria: '性能优化', points: 20 },
      { criteria: '文档说明', points: 10 }
    ],
    solution: `class MyPromise {
  constructor(executor) {
    this.state = 'pending'
    this.value = undefined
    this.reason = undefined
    this.onFulfilledCallbacks = []
    this.onRejectedCallbacks = []
    
    const resolve = (value) => {
      if (this.state === 'pending') {
        this.state = 'fulfilled'
        this.value = value
        this.onFulfilledCallbacks.forEach(callback => callback(value))
      }
    }
    
    const reject = (reason) => {
      if (this.state === 'pending') {
        this.state = 'rejected'
        this.reason = reason
        this.onRejectedCallbacks.forEach(callback => callback(reason))
      }
    }
    
    try {
      executor(resolve, reject)
    } catch (error) {
      reject(error)
    }
  }
  
  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : value => value
    onRejected = typeof onRejected === 'function' ? onRejected : reason => { throw reason }
    
    const promise2 = new MyPromise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        setTimeout(() => {
          try {
            const x = onFulfilled(this.value)
            resolvePromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }
        })
      } else if (this.state === 'rejected') {
        setTimeout(() => {
          try {
            const x = onRejected(this.reason)
            resolvePromise(promise2, x, resolve, reject)
          } catch (error) {
            reject(error)
          }
        })
      } else {
        this.onFulfilledCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onFulfilled(this.value)
              resolvePromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }
          })
        })
        
        this.onRejectedCallbacks.push(() => {
          setTimeout(() => {
            try {
              const x = onRejected(this.reason)
              resolvePromise(promise2, x, resolve, reject)
            } catch (error) {
              reject(error)
            }
          })
        })
      }
    })
    
    return promise2
  }
  
  catch(onRejected) {
    return this.then(null, onRejected)
  }
  
  finally(callback) {
    return this.then(
      value => MyPromise.resolve(callback()).then(() => value),
      reason => MyPromise.resolve(callback()).then(() => { throw reason })
    )
  }
  
  static resolve(value) {
    if (value instanceof MyPromise) {
      return value
    }
    return new MyPromise(resolve => resolve(value))
  }
  
  static reject(reason) {
    return new MyPromise((resolve, reject) => reject(reason))
  }
  
  static all(promises) {
    return new MyPromise((resolve, reject) => {
      const results = []
      let count = 0
      
      for (let i = 0; i < promises.length; i++) {
        MyPromise.resolve(promises[i]).then(
          value => {
            results[i] = value
            count++
            if (count === promises.length) {
              resolve(results)
            }
          },
          reason => reject(reason)
        )
      }
    })
  }
  
  static race(promises) {
    return new MyPromise((resolve, reject) => {
      for (let i = 0; i < promises.length; i++) {
        MyPromise.resolve(promises[i]).then(resolve, reject)
      }
    })
  }
}

// 辅助函数：处理Promise解析过程
function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    reject(new TypeError('Chaining cycle'))
    return
  }
  
  if (x instanceof MyPromise) {
    x.then(resolve, reject)
  } else {
    resolve(x)
  }
}`,
    solutionExplanation: '通过实现Promise的基本功能、链式调用、错误处理和静态方法，实现一个简单的Promise类',
    keyPoints: ['Promise', '链式调用', '错误处理', '静态方法'],
    discussions: [
      {
        id: 5,
        username: '孙八',
        userAvatar: 'https://placeholder.com/40x40',
        content: '这个练习让我理解了Promise的原理和实现',
        time: '2024-03-11 14:20',
        likes: 18,
        replies: []
      }
    ],
    initialCode: `// 在这里实现一个简单的Promise类
// 提示：实现Promise的基本功能、链式调用、错误处理和静态方法

class MyPromise {
  constructor(executor) {
    // 实现Promise构造函数
  }
  
  then(onFulfilled, onRejected) {
    // 实现then方法
  }
  
  catch(onRejected) {
    // 实现catch方法
  }
  
  finally(callback) {
    // 实现finally方法
  }
  
  static resolve(value) {
    // 实现静态resolve方法
  }
  
  static reject(reason) {
    // 实现静态reject方法
  }
  
  static all(promises) {
    // 实现静态all方法
  }
  
  static race(promises) {
    // 实现静态race方法
  }
}

// 测试代码
const promise = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve('成功')
  }, 1000)
})

promise
  .then(value => {
    console.log(value)
    return '链式调用'
  })
  .then(value => {
    console.log(value)
    throw new Error('错误')
  })
  .catch(error => {
    console.error(error)
  })
  .finally(() => {
    console.log('完成')
  })

// 测试静态方法
MyPromise.all([
  MyPromise.resolve(1),
  MyPromise.resolve(2),
  MyPromise.resolve(3)
]).then(values => {
  console.log('all结果:', values)
})

MyPromise.race([
  new MyPromise(resolve => setTimeout(() => resolve(1), 1000)),
  new MyPromise(resolve => setTimeout(() => resolve(2), 500))
]).then(value => {
  console.log('race结果:', value)
})
`
  }
])

// 计算属性
const filteredPractices = computed(() => {
  let result = practices.value
  if (selectedCategory.value) {
    result = result.filter(practice => practice.category === selectedCategory.value)
  }
  if (selectedDifficulty.value) {
    result = result.filter(practice => practice.difficulty === selectedDifficulty.value)
  }
  if (selectedStatus.value) {
    result = result.filter(practice => {
      if (selectedStatus.value === 'not_started') return !practice.progress
      if (selectedStatus.value === 'in_progress') return practice.progress > 0 && practice.progress < 100
      if (selectedStatus.value === 'completed') return practice.progress === 100
      return true
    })
  }
  return result
})

// 方法
const handleCategoryChange = () => {
  currentPage.value = 1
  // 这里可以调用后端API获取分类练习
}

const handleDifficultyChange = () => {
  currentPage.value = 1
  // 这里可以调用后端API获取难度练习
}

const handleStatusChange = () => {
  currentPage.value = 1
  // 这里可以调用后端API获取状态练习
}

const handleSizeChange = (val) => {
  pageSize.value = val
  // 这里可以调用后端API获取新的分页数据
}

const handleCurrentChange = (val) => {
  currentPage.value = val
  // 这里可以调用后端API获取新的分页数据
}

const getDifficultyTag = (difficulty) => {
  const types = {
    '入门': 'info',
    '简单': 'success',
    '中等': 'warning',
    '困难': 'danger',
    '挑战': 'primary'
  }
  return types[difficulty] || 'default'
}

const getProgressStatus = (progress) => {
  if (progress === 100) return 'success'
  if (progress >= 60) return 'warning'
  return ''
}

// 练习详情
const practiceDialogVisible = ref(false)
const selectedPractice = ref(null)
const activeTab = ref('description')
const codeContent = ref('')
const codeOutput = ref('')
const newComment = ref('')
const editor = ref(null)
const editorContainer = ref(null)
const replyToComment = ref(null)
const replyContent = ref('')

// 初始化Monaco编辑器
const initEditor = () => {
  if (editorContainer.value && !editor.value) {
    editor.value = monaco.editor.create(editorContainer.value, {
      value: selectedPractice.value?.initialCode || '',
      language: 'javascript',
      theme: 'vs-dark',
      automaticLayout: true,
      minimap: {
        enabled: true
      },
      fontSize: 14,
      lineNumbers: 'on',
      roundedSelection: false,
      scrollBeyondLastLine: false,
      readOnly: false,
      cursorStyle: 'line',
      tabSize: 2,
      wordWrap: 'on',
      folding: true,
      autoClosingBrackets: 'always',
      autoClosingQuotes: 'always',
      formatOnPaste: true,
      formatOnType: true,
      suggestOnTriggerCharacters: true,
      acceptSuggestionOnEnter: 'on',
      acceptSuggestionOnCommitCharacter: true,
      snippetSuggestions: 'inline',
      wordBasedSuggestions: 'matchingDocuments',
      parameterHints: {
        enabled: true
      }
    })
    
    // 监听代码变化
    editor.value.onDidChangeModelContent(() => {
      codeContent.value = editor.value.getValue()
    })
    
    // 设置初始代码
    codeContent.value = selectedPractice.value?.initialCode || ''
    
    // 添加编辑器快捷键
    editor.value.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter, () => {
      runCode()
    })
    
    editor.value.addCommand(monaco.KeyMod.CtrlCmd | monaco.KeyCode.KeyS, () => {
      submitCode()
    })
  }
}

// 销毁编辑器
const destroyEditor = () => {
  if (editor.value) {
    editor.value.dispose()
    editor.value = null
  }
}

// 重置编辑器
const resetEditor = () => {
  if (editor.value && selectedPractice.value) {
    editor.value.setValue(selectedPractice.value.initialCode || '')
    codeContent.value = selectedPractice.value.initialCode || ''
  }
  codeOutput.value = ''
}

// 运行代码
const runCode = () => {
  try {
    // 创建一个安全的执行环境
    const safeEval = new Function('console', codeContent.value)
    
    // 重写console对象
    const logs = []
    const customConsole = {
      log: (...args) => {
        logs.push(args.map(arg => 
          typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
        ).join(' '))
      },
      error: (...args) => {
        logs.push('Error: ' + args.map(arg => 
          typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
        ).join(' '))
      },
      warn: (...args) => {
        logs.push('Warning: ' + args.map(arg => 
          typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
        ).join(' '))
      },
      info: (...args) => {
        logs.push('Info: ' + args.map(arg => 
          typeof arg === 'object' ? JSON.stringify(arg, null, 2) : String(arg)
        ).join(' '))
      },
      table: (data) => {
        if (Array.isArray(data)) {
          if (data.length === 0) {
            logs.push('(empty array)')
            return
          }
          
          // 简单的表格实现
          const headers = Object.keys(data[0])
          const rows = data.map(item => headers.map(key => item[key]))
          
          logs.push(headers.join(' | '))
          logs.push(headers.map(() => '---').join(' | '))
          rows.forEach(row => logs.push(row.join(' | ')))
        } else {
          logs.push('table() expects an array of objects')
        }
      },
      time: (label) => {
        logs.push(`Timer started: ${label}`)
      },
      timeEnd: (label) => {
        logs.push(`Timer ended: ${label}`)
      },
      clear: () => {
        logs.length = 0
      }
    }
    
    // 执行代码
    safeEval(customConsole)
    
    // 显示输出
    codeOutput.value = logs.join('\n')
  } catch (error) {
    codeOutput.value = `Error: ${error.message}\n${error.stack}`
  }
}

// 提交代码
const submitCode = () => {
  if (!codeContent.value.trim()) {
    ElMessage.warning('请输入代码')
    return
  }
  
  // 这里实现代码提交逻辑
  ElMessage.success('代码提交成功，正在评测...')
  
  // 模拟评测过程
  setTimeout(() => {
    // 随机生成评分
    const score = Math.floor(Math.random() * 30) + 70 // 70-100之间的随机数
    
    let feedback = ''
    if (score >= 90) {
      feedback = '代码实现非常优秀，逻辑清晰，性能良好。'
    } else if (score >= 80) {
      feedback = '代码实现良好，有少量可以优化的地方。'
    } else if (score >= 70) {
      feedback = '代码基本实现了功能，但还有改进空间。'
    } else {
      feedback = '代码存在一些问题，需要进一步改进。'
    }
    
    ElMessageBox.alert(
      `恭喜你！代码评测完成！\n\n得分：${score}/100\n\n评语：${feedback}`,
      '评测结果',
      {
        confirmButtonText: '确定',
        callback: () => {
          // 更新练习进度
          if (selectedPractice.value) {
            // 如果分数高于当前进度，则更新进度
            const newProgress = Math.max(selectedPractice.value.progress || 0, score)
            selectedPractice.value.progress = newProgress
            
            if (newProgress === 100) {
              ElMessage.success('练习完成！获得 ' + selectedPractice.value.points + ' 积分')
            } else {
              ElMessage.success(`练习进度更新为 ${newProgress}%`)
            }
          }
        }
      }
    )
  }, 2000)
}

// 清除输出
const clearOutput = () => {
  codeOutput.value = ''
}

// 点赞评论
const likeComment = (comment) => {
  comment.likes++
  ElMessage.success('点赞成功')
}

// 回复评论
const replyComment = (comment) => {
  replyToComment.value = comment
  replyContent.value = ''
}

// 取消回复
const cancelReply = () => {
  replyToComment.value = null
  replyContent.value = ''
}

// 提交回复
const submitReply = () => {
  if (!replyContent.value.trim()) {
    ElMessage.warning('请输入回复内容')
    return
  }
  
  if (replyToComment.value) {
    // 添加回复
    if (!replyToComment.value.replies) {
      replyToComment.value.replies = []
    }
    
    replyToComment.value.replies.push({
      id: Date.now(),
      username: '当前用户',
      userAvatar: 'https://placeholder.com/40x40',
      content: replyContent.value,
      time: new Date().toLocaleString(),
      likes: 0
    })
    
    ElMessage.success('回复发表成功')
    replyToComment.value = null
    replyContent.value = ''
  }
}

// 提交评论
const submitComment = () => {
  if (!newComment.value.trim()) {
    ElMessage.warning('请输入评论内容')
    return
  }
  
  // 添加评论
  if (selectedPractice.value) {
    if (!selectedPractice.value.discussions) {
      selectedPractice.value.discussions = []
    }
    
    selectedPractice.value.discussions.unshift({
      id: Date.now(),
      username: '当前用户',
      userAvatar: 'https://placeholder.com/40x40',
      content: newComment.value,
      time: new Date().toLocaleString(),
      likes: 0,
      replies: []
    })
    
    ElMessage.success('评论发表成功')
    newComment.value = ''
  }
}

// 监听标签页变化
const handleTabChange = (tab) => {
  if (tab === 'coding') {
    // 切换到编码标签页时初始化编辑器
    setTimeout(() => {
      initEditor()
    }, 100)
  }
}

// 监听对话框关闭
const handleDialogClose = () => {
  // 销毁编辑器
  destroyEditor()
}

const startPractice = (practice) => {
  selectedPractice.value = practice
  practiceDialogVisible.value = true
  activeTab.value = 'coding'
}

const viewPracticeDetail = (practice) => {
  selectedPractice.value = practice
  practiceDialogVisible.value = true
  activeTab.value = 'description'
}

// 组件挂载时初始化
onMounted(() => {
  // 这里可以加载练习数据
})
</script>

<style scoped>
.practice-area {
  padding: 20px;
}

.practice-header {
  text-align: center;
  margin-bottom: 30px;
}

.practice-header h2 {
  margin-bottom: 10px;
  color: #303133;
}

.practice-header p {
  color: #606266;
}

.filter-section {
  display: flex;
  gap: 20px;
  margin-bottom: 30px;
}

.practice-card {
  margin-bottom: 20px;
  transition: transform 0.3s;
}

.practice-card:hover {
  transform: translateY(-5px);
}

.practice-info {
  padding: 14px;
}

.practice-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  margin-bottom: 10px;
}

.practice-header h4 {
  margin: 0;
  flex: 1;
}

.practice-desc {
  color: #606266;
  margin: 10px 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.practice-meta {
  display: flex;
  gap: 15px;
  color: #909399;
  margin: 10px 0;
}

.practice-progress {
  margin: 10px 0;
}

.practice-actions {
  display: flex;
  justify-content: space-between;
  margin-top: 10px;
}

.pagination-section {
  margin-top: 20px;
  text-align: center;
}

.practice-detail {
  padding: 20px;
}

.detail-header {
  margin-bottom: 20px;
}

.detail-meta {
  margin-top: 10px;
  display: flex;
  gap: 15px;
  align-items: center;
}

.coding-environment {
  display: flex;
  flex-direction: column;
  gap: 20px;
}

.editor-section {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.editor-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background: #f5f7fa;
  border-bottom: 1px solid #dcdfe6;
}

.editor-actions {
  display: flex;
  gap: 10px;
}

.code-editor {
  padding: 10px;
}

.output-section {
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}

.output-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding: 10px;
  background: #f5f7fa;
  border-bottom: 1px solid #dcdfe6;
}

.output-content {
  padding: 10px;
  background: #1e1e1e;
  color: #fff;
  min-height: 200px;
  max-height: 400px;
  overflow-y: auto;
}

.solution-content {
  padding: 20px;
}

.solution-code {
  background: #1e1e1e;
  color: #fff;
  padding: 15px;
  border-radius: 4px;
  margin: 10px 0;
  overflow-x: auto;
}

.key-point-tag {
  margin: 5px;
}

.discussion-content {
  padding: 20px;
}

.discussion-item {
  margin-bottom: 20px;
  padding-bottom: 20px;
  border-bottom: 1px solid #dcdfe6;
}

.comment-header {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 10px;
}

.username {
  font-weight: bold;
}

.time {
  color: #909399;
  font-size: 12px;
}

.comment-content {
  margin: 10px 0;
}

.comment-actions {
  display: flex;
  gap: 10px;
}

.comment-input {
  margin-top: 20px;
}

.comment-input .el-button {
  margin-top: 10px;
  float: right;
}

.replies-list {
  margin-left: 40px;
  margin-top: 10px;
  padding-left: 10px;
  border-left: 2px solid #ebeef5;
}

.reply-item {
  margin-bottom: 15px;
  padding-bottom: 15px;
  border-bottom: 1px dashed #ebeef5;
}

.reply-header {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 5px;
}

.reply-content {
  margin: 5px 0;
  color: #606266;
}

.reply-actions {
  display: flex;
  gap: 10px;
  margin-top: 5px;
}

.reply-input {
  margin-top: 10px;
  margin-left: 40px;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
}

.reply-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
  margin-top: 10px;
}

.editor-container {
  height: 400px;
  border: 1px solid #dcdfe6;
  border-radius: 4px;
}
</style> 